import React, { createRef, useEffect, useRef, useState } from "react";
import classNames from "classnames";
import Taro, { useRouter } from "@tarojs/taro";
import dayjs from "dayjs";
import { debounce } from "debounce";
import { inject, observer } from "mobx-react";
import { TitleBar } from "../../../../src/components/title-bar";
import NoProject from "../../../assets/no-project.png";
import NoFile from "../../../assets/no-file.png";
import NoConfirm from "../../../assets/no-confirm.png";
import "./index.scss";
import { StackAvatars } from "../../../../src/components/stack-avatars";
import avatar from "../../../assets/avatar.png";
import { LiquidFill } from "../../../../src/components/liquid-fill";
import { Countdown, farForm } from "../../../../src/components/count-down";
import { RootStore } from "../../../../src/store/root-store";
import {
  fetchListing,
  fetchMember,
  fetchOutNumber,
  fetchPartner,
  fetchRecordList,
  fetchSchedule,
} from "../../../../src/api";
import {
  IListing,
  IMember,
  IOutNumber,
  IPartner,
  IRecordList,
  ISchedule,
} from "../../../../src/interfaces";
import {
  matchSuffixType,
  matchType,
} from "../../../../src/utils/check-file-type";
import { getOssUrl } from "../../../../src/utils";

/** 基本信息 单行 */
const BaseInfoLine = ({
  icon,
  name,
  value,
}: {
  icon: string;
  name: string;
  value: React.ReactNode;
}) => {
  return (
    <div className="info-line">
      <div className="left">
        <span className={classNames("iconfont", icon)}></span>
        {name}
      </div>
      <div className="right">{value}</div>
    </div>
  );
};

const NoData = ({ img, text }: { img: string; text: string }) => {
  return (
    <div className="no-data">
      <img className="no-data-img" src={img} alt="" />
      <p className="no-data-text">{text}</p>
    </div>
  );
};

/** 确认项 进行中/已结束 */
const CheckProgressTag = ({
  count,
  title,
  active,
  onClick,
}: {
  count: number;
  title: string;
  active?: boolean;
  onClick: () => void;
}) => {
  return (
    <div
      className={classNames("progress-tag", {
        active,
      })}
      onClick={onClick}
    >
      {title}·{count}
    </div>
  );
};

/** 项目计划 三角 进度条 */
const ProgressBarItem = ({
  name,
  current,
  total,
}: {
  name: string;
  current: number;
  total: number;
}) => {
  return (
    <div className="rate-item">
      <div className="rate-total">
        <span className="title ellipsis">{name}</span>
        <span className="number">
          {current}/{total}
        </span>
      </div>
      <div
        className={classNames("rate-current", {
          empty: !current,
        })}
        style={{ width: `${parseInt(`${(current / total) * 100}`)}%` }}
      ></div>
    </div>
  );
};

/** 项目进度 */
const ProgressItem = (channel: ISchedule) => {
  const ratesRef = createRef<HTMLDivElement>();
  useEffect(() => {
    const handleStopPropagation = (e) => {
      e.stopPropagation();
    };
    if (ratesRef && ratesRef.current) {
      ratesRef.current.addEventListener("scroll", handleStopPropagation, true);
    }
    return () => {
      if (ratesRef && ratesRef.current) {
        ratesRef.current.removeEventListener(
          "scroll",
          handleStopPropagation,
          true
        );
      }
    };
  }, []);
  return (
    <div
      className={classNames("progress-item", {
        empty: !channel.list || !channel.list.length,
      })}
    >
      <div className="rates hide-scroll-bar" ref={ratesRef}>
        <div className="progress-name">{channel.channelName}</div>
        {channel.list.map((item) => {
          return (
            <ProgressBarItem
              key={item.phaseId}
              name={item.phaseName}
              current={+item.done}
              total={+item.total}
            />
          );
        })}
      </div>
    </div>
  );
};

/** 确认项 */
const CheckItem = ({
  process,
  channelId,
  ...item
}: IListing & { process: number; channelId: string }) => {
  // process:0 进行中；1 已结束
  const [countHidden, setCountHidden] = useState(false);
  const checkerRef = createRef<HTMLDivElement>();
  const router = useRouter();
  useEffect(() => {
    if (!checkerRef.current) return;
    const width = checkerRef.current.clientWidth;
    const pWidth = checkerRef.current.parentElement!.clientWidth;
    if (width / pWidth > 0.8) {
      setCountHidden(true);
    }
  }, []);
  let checker: React.ReactNode = "";
  if (item.confirmType === "open") {
    checker = "公开";
  } else {
    let names = (item.confirmedBys || []).map((i) => {
      if (i.nickName.length > 3) {
        return i.nickName.substring(0, 3) + "...";
      }
      return i.nickName;
    });
    if (names.length > 4) {
      names = names.slice(0, 4);
      names.push(`+${names.length - 4}`);
    }
    checker = (
      <>
        {names.map((n) => {
          return (
            <span key={n} className="checker-name">
              {n}
            </span>
          );
        })}
      </>
    );
  }
  const jump = () => {
    Taro.navigateTo({
      url: `/pages/project-check-detail/index?spaceId=${router.params.spaceId}&listingId=${item.id}`,
    });
  };
  return (
    <div className="check-item" key={item.id} onClick={jump}>
      <div className="title ellipsis">{item.name}</div>
      {process === 0 ? (
        <div className="countdown">
          <span className="iconfont icon-alarm-line"></span>
          倒计时：
          <Countdown time={item.endDate} />
        </div>
      ) : (
        <div className="countdown">
          {process === 0 && <span className="iconfont icon-alarm-line"></span>}
          截止日期：{dayjs(item.endDate).format("YYYY/MM/DD")}
        </div>
      )}
      <div className="checker-wrapper">
        <div className="checker ellipsis" ref={checkerRef}>
          确认人：
          <span className={`${item.confirmType === "open" ? "tag" : ""}`}>
            {checker}
          </span>
        </div>
      </div>
      <div className="line"></div>
      <div className="count-process">
        {process === 0 ? (
          <div
            className="waiting"
            style={{
              width: `${(+item.unconfirmed / +item.allItems) * 100}%`,
              display: !item.unconfirmed ? "none" : "block",
            }}
          ></div>
        ) : (
          <div
            className="waiting"
            style={{
              width: `${(+item.overdue / +item.allItems) * 100}%`,
              background: "#FCC541",
              display: !item.overdue ? "none" : "block",
            }}
          ></div>
        )}
        {process === 0 ? (
          <div
            className="modifing"
            style={{
              width: `${
                ((+item.needModify + +item.unconfirmed) / +item.allItems) * 100
              }%`,
              display: !(+item.needModify + +item.unconfirmed)
                ? "none"
                : "block",
            }}
          ></div>
        ) : (
          <div
            className="modifing"
            style={{
              width: `${
                ((+item.needModify + +item.overdue) / +item.allItems) * 100
              }%`,
              display: !(+item.needModify + +item.overdue) ? "none" : "block",
            }}
          ></div>
        )}

        <div className="checked" style={{ width: `100%` }}></div>
      </div>
      <div className="count-number">
        <div className="left">
          <div className="count-waiting">
            {process === 0 ? (
              <>
                <div className="dot" style={{ background: "#DBDEE6" }}></div>
                <div className="number">待确认：{item.unconfirmed}</div>
              </>
            ) : (
              <>
                <div className="dot" style={{ background: "#FCC541" }}></div>
                <div className="number">已超期：{item.overdue}</div>
              </>
            )}
          </div>
          <div className="count-modifing">
            <div className="dot" style={{ background: "#FF7875" }}></div>
            <div className="number">待修改：{item.needModify}</div>
          </div>
          <div className="count-checked">
            <div className="dot" style={{ background: "#3DD1AF" }}></div>
            <div className="number">已确认：{item.haveConfirmed}</div>
          </div>
        </div>
        <div className="right">共{item.allItems}项</div>
      </div>
    </div>
  );
};

/** 附件 */
const Attachment = ({
  img,
  name,
  time,
  username,
  onClick,
}: {
  img: string;
  name: string;
  username: string;
  time: string;
  onClick: () => void;
}) => {
  return (
    <div className="attachment" onClick={onClick}>
      <div className="left">
        <span className={`iconfont ${img}`}></span>
      </div>
      <div className="right">
        <div className="name ellipsis">{name}</div>
        <div className="username ellipsis">
          {username} 上传于{farForm(time)}
        </div>
      </div>
    </div>
  );
};

interface Props {
  rootStore?: RootStore;
}

export const Index = ({ rootStore }: Props) => {
  const { curChannelInfo } = rootStore as RootStore;
  const { id: channelId } = curChannelInfo;
  const { router } = Taro.getCurrentInstance();
  const spaceId = (router && router.params && router.params.spaceId) || "";
  const listRef = createRef<HTMLDivElement>();

  const [checkProcessStatus, setCheckProcessStatus] = useState(0);
  const [baseInfo, setBaseInfo] = useState<IPartner | undefined>();
  useEffect(() => {
    /** 项目信息 */
    const init = async () => {
      Taro.showLoading();
      const { code, data, message } = await fetchPartner(spaceId);
      setBaseInfo(data);
      Taro.hideLoading();
    };
    init();
  }, []);

  const [statistics, setStatistics] = useState<IOutNumber | undefined>();
  useEffect(() => {
    /** 数据概览 */
    const init = async () => {
      const { code, data, message } = await fetchOutNumber(spaceId);
      setStatistics(data);
    };
    init();
  }, []);
  const [members, setMembers] = useState<IMember[] | undefined>();
  useEffect(() => {
    /** 合作方 */
    const init = async () => {
      const { code, data, message } = await fetchMember(spaceId);
      setMembers(data);
    };
    init();
  }, []);

  const [progress, setProgress] = useState<ISchedule[]>([]);
  useEffect(() => {
    /** 进度 */
    const init = async () => {
      const { code, data, message } = await fetchSchedule(spaceId);
      setProgress(data);
    };
    init();
  }, []);

  const [listing, setListing] = useState<IListing[]>([]);
  const [curListing, setCurListing] = useState<IListing[]>([]);
  useEffect(() => {
    /** 确认清单 */
    const init = async () => {
      const { code, data, message } = await fetchListing(spaceId);
      setListing(data);
      setCurListing(
        data?.filter((f) => {
          // 已结束包括超期的
          if (checkProcessStatus === 1 && +f.state === 2) return true;
          return +f.state === checkProcessStatus;
        })
      );
    };
    init();
  }, []);
  useEffect(() => {
    setCurListing(
      listing?.filter((f) => {
        // 已结束包括超期的
        if (checkProcessStatus === 1 && +f.state === 2) return true;
        return +f.state === checkProcessStatus;
      })
    );
  }, [checkProcessStatus]);

  const [recordList, setRecordList] = useState<IRecordList[]>([]);
  /** 页码 */
  const curPage = useRef(0);
  /** 是否已加载完成 */
  const fetchAll = useRef(false);
  /** 是否正在加载文件 */
  const fetchingFile = useRef(false);

  const fetchMoreRecordList = debounce(async () => {
    if (fetchingFile.current) return;
    fetchingFile.current = true;
    const { code, data, message } = await fetchRecordList(spaceId, {
      current: curPage.current + 1,
      pageSize: 5,
    });
    fetchingFile.current = false;
    if (code !== 0) return;
    let newRecordList: IRecordList[] = [];
    if (data.current === 1) {
      newRecordList = data.list;
    } else {
      newRecordList = recordList.concat(data.list);
    }
    curPage.current = data.current;
    setRecordList(newRecordList);
    if (newRecordList.length >= data.total) {
      fetchAll.current = true;
    }
  }, 500);

  useEffect(() => {
    /** 最新上传文件 */
    fetchMoreRecordList();
  }, []);
  useEffect(() => {
    if (!listRef.current) return;
    const container = listRef.current.parentElement;
    if (!container) return;
    container.onscroll = (e) => {
      const { scrollHeight, offsetHeight, scrollTop } =
        e.target as HTMLDivElement;
      if (scrollHeight - offsetHeight - scrollTop > 5) {
        if (fetchAll.current) return;
        fetchMoreRecordList();
      }
    };
    return () => {
      container.onscroll = () => {};
    };
  }, [fetchMoreRecordList]);

  const handleFileClick = (record: IRecordList) => {
    if (record.type === 200) {
      // 文件夹
      Taro.navigateTo({
        url: `/pages/file/index?spaceId=${spaceId}&channelId=${record.channelId}&filename=${record.name}&dirId=${record.id}`,
      });
    } else if (record.type === 500) {
      // 预览
      const type = matchSuffixType(record.extensionName, record.type);

      Taro.navigateTo({
        url: `/pages/file-preview/index?spaceId=${spaceId}&channelId=${
          record.channelId
        }&fileId=${record.id}&canPreview=${!!type}`,
      });
    } else {
      // 链接
      Taro.navigateTo({
        url: `/pages/file-preview/index?spaceId=${spaceId}&channelId=${
          record.channelId
        }&fileId=${record.id}&name=${record.name}&urlLink=${encodeURIComponent(
          record.urlLink || ""
        )}`,
      });
    }
  };
  return (
    <div className="index-tab" ref={listRef}>
      <TitleBar name={baseInfo && baseInfo.projectName} />
      <div className="base-info card clearfix">
        <BaseInfoLine
          icon="icon-calendar-line"
          name="项目周期"
          value={(() => {
            let text = "";
            if (baseInfo && baseInfo.startDate && +baseInfo.startDate > 0) {
              text += dayjs(baseInfo.startDate).format("YYYY/MM/DD");
            }
            text += `-`;
            if (baseInfo && baseInfo.endDate && +baseInfo.endDate > 0) {
              text += dayjs(baseInfo.endDate).format("YYYY/MM/DD");
            }
            return text;
          })()}
        />
        <BaseInfoLine
          icon="icon-External-principal"
          name="项目负责人"
          value={baseInfo?.headName}
        />
        <BaseInfoLine
          icon="icon-phone-line"
          name="联系电话"
          value={baseInfo?.phoneNumber}
        />
        <BaseInfoLine
          icon="icon-team-line"
          name="合作方成员"
          value={
            <StackAvatars
              maxLength={5}
              showCount={
                (members || []).filter((m) => m.memberType === "in").length > 4
              }
              imgs={
                members
                  ?.filter((m) => m.memberType === "in")
                  .map((m) => ({
                    src: getOssUrl(m.img || {}),
                    text: m.nickName,
                  })) || []
              }
            />
          }
        />
      </div>
      <TitleBar name="数据概览" />
      <div className="statistics card clearfix">
        <div className="line1">
          <div className="left">
            <div className="name">
              <span className="iconfont icon-wancheng"></span>
              <div>项目完成情况</div>
            </div>
            <div className="value">
              <div>
                {statistics?.taskCompleted || 0}/{statistics?.taskSum || 0}
              </div>
            </div>
          </div>
          <div className="right">
            <LiquidFill
              value={
                statistics && statistics.taskSum
                  ? +statistics.taskCompleted / +statistics.taskSum
                  : 0
              }
            />
          </div>
        </div>
        <div className="line2">
          <div className="left">
            <div className="name">
              <span className="iconfont icon-file-upload-line"></span>
              <div>文件总数</div>
            </div>
            <div className="value">
              <div>{statistics?.fileNumber || 0}</div>
            </div>
          </div>
          <div className="right">
            <div className="name">
              <span className="iconfont icon-querenrizhi"></span>
              <div>审阅意见</div>
            </div>
            <div className="value">
              <div>
                {statistics?.issueCompleted || 0}/{statistics?.issueSum || 0}
              </div>
            </div>
          </div>
        </div>
      </div>
      <TitleBar name="项目进度" />
      <div className="progress">
        {progress?.length > 0 ? (
          progress?.map((p) => {
            return <ProgressItem key={p.channelId} {...p} />;
          })
        ) : (
          <NoData img={NoProject} text="暂无项目进度" />
        )}
      </div>
      <TitleBar name="确认项" />
      <div className="checks">
        <div className="checks-status-tags">
          <CheckProgressTag
            active={checkProcessStatus === 0}
            title="进行中"
            count={listing?.filter((l) => +l.state === 0).length || 0}
            onClick={() => setCheckProcessStatus(0)}
          />
          <CheckProgressTag
            active={checkProcessStatus === 1}
            title="已结束"
            count={listing?.filter((l) => +l.state !== 0).length || 0}
            onClick={() => setCheckProcessStatus(1)}
          />
        </div>
        {curListing?.length > 0 ? (
          curListing?.map((item) => {
            return (
              <CheckItem
                process={checkProcessStatus}
                channelId={channelId}
                key={item.id}
                {...item}
              />
            );
          })
        ) : (
          <NoData img={NoConfirm} text="暂无确认项" />
        )}
      </div>
      <TitleBar name="最新上传文件" />
      <div className="uploads">
        {recordList?.length > 0 ? (
          recordList?.map((record) => {
            return (
              <Attachment
                onClick={() => handleFileClick(record)}
                key={record.id}
                img={
                  matchSuffixType(record.extensionName, record.type) ||
                  matchType["icon-a-CannotPreview"]
                }
                name={record.name}
                username={record.creator.nickName}
                time={record.createdAt}
              />
            );
          })
        ) : (
          <NoData img={NoFile} text="暂无文件" />
        )}
      </div>
    </div>
  );
};

export const IndexTab = observer(inject("rootStore")(Index));
